﻿#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<vector>
#include<list>
using namespace std;

////char ascall 编码 -》英文
////int main()
////{
////	char ch1 = 'a';
////	char ch2 = 97;
////	cout << ch1 << endl;
////	cout << ch2 << endl;
////
////	char str1[] = "中国";
////	cout << strlen(str1) << endl;
////
////	str1[3] = -7;
////	cout << str1 << endl;
////
////	str1[3] = -8;
////	cout << str1 << endl;
////
////	str1[3] = -5;
////	cout << str1 << endl;
////
////	wchar_t wch;//宽字节，2byte,能更好的表示unicode等编码
////	char ch;
////	cout << sizeof(wch) << endl;
////	cout << sizeof(ch) << endl;
////	return 0;
////}
//
////int main()
////{
////	string s1;
////	string s2("hello bit");
////	string s3(s2);
////	string s4 = "hello bit";
////	string s5(s4, 3, string::npos);
////	cout << s1 << endl;
////	cout << s2 << endl;
////	cout << s3 << endl; 
////	cout << s4 << endl;
////
////	cout << s5 << endl;
////
////	const char* url = "https://mp.csdn.net/mp_blog/manage/article?spm=1010.2135.3001.5448";
////	string s6(url, 4);
////	cout << s6 << endl;
////	string s7(10, 'x');
////	cout << s7 << endl;
////	s7 = s2;
////	cout << s7 << endl;
////	
////	return 0;
////}
////
////int main()
////{
////	string s1;
////	string s2("hello bit");
////
////	//三种遍历方式
////	//1、下标+[]
////	for (size_t i = 0; i < s2.size(); i++)
////	{
////		s2[i] = 'x';
////	}
////	cout << endl;
////	for (size_t i = 0; i < s2.size(); i++)
////	{
////		cout << s2[i] <<" ";
////		cout << s2.at(i) << " ";
////		cout << s2.operator[](i) << " ";
////	}
////	cout << endl;
////
////	//2、迭代器
////	//[begin(),end())  end()返回的不是最后一个数据位置的迭代器，返回的是最后一个位置的下一位置
////	//也要注意的是，C++中凡是给迭代器一般都是给[)左闭右开的区间
////	//迭代器是类似指针一样的东西
////
////	string::iterator it = s2.begin();
////	while (it != s2.end())
////	{
////		cout << *it << " ";
////		it++;
////	}
////	cout << endl;
////
////	//迭代器意义：就像string,vector支持[]遍历，但是list,map等等容器不支持[]
////	//我们就要有迭代器遍历，所以迭代器是一种统一的方式
////
////	vector<int> v = { 1,2,3,4 };
////	vector<int>::iterator vit = v.begin();
////	while (vit != v.end())
////	{
////		cout << *vit << " ";
////		vit++;
////	}
////	cout << endl;
////
////	list<int> lt = { 1,2,3,4 };
////	list<int>::iterator ltit = lt.begin();
////	while (ltit != lt.end())
////	{
////		cout << *ltit << " ";
////		++ltit;
////	}
////	cout << endl;
////
////	//反向迭代器
////	string s3("123456");
////	string::iterator it3 = s3.begin();
////	while (it3 != s3.begin())
////	{
////		*it3 += 5;
////		cout << *it3 << " ";
////	}
////	cout << endl;
////	string::reverse_iterator rit = s3.rbegin();
////	while (rit != s3.rend())
////	{
////		cout << *rit << " ";
////		++rit;
////	}
////	cout << endl;
////
////	//3、c++11提供范围for,特点：写起来简洁
////	//依次取容器中的数据，复制给e，自动判断结束
////	for (auto& e : s3)
////	{
////		e += 1;
////	}
////	cout << endl;
////
////	for (auto e : s3)
////	{
////		cout << e << " ";
////	}
////	cout << endl;
////
////}
//
//int main()
//{
//	string s1;
//	s1.push_back('h');
//	s1.push_back('e');
//	s1.push_back('l');
//	s1.push_back('l');
//	s1.push_back('o');
//	
//	s1.append("world");
//	cout << s1 << endl;
//
//	string s2("!!!!");
//	s1.append(s2);
//	s1.append(s2.begin(), s2.end());
//	cout << s1 << endl;
//
//	//实际中最喜欢用+=
//	s1 += ' ';
//	s1 += "你好";
//	s1 += s2;
//	cout << s1 << endl;
//
//	//尽量少用insert，因为底层实现是数组，头部或者中间插入需要挪动数据
//
//	s1.insert(0, "x");
//	cout << s1 << endl;
//
//	s1.insert(3, "uuuu");
//	cout << s1 << endl;
//
//	//s1.insert(300, "nnnn");  //报错,字符串没那么大
//	s1.erase(0, 1);
//	cout << s1 << endl;
//
//	s1.erase(0, 3);
//	cout << s1 << endl;
//
//	s1.erase(3, 10);
//	cout << s1 << endl;
//
//	s1.erase(3, 100);
//	cout << s1 << endl;
//
//	s1.erase();
//	cout << s1 << endl;
//
//	return 0;
//}

//
//int main()
//{
//	string s1;
//	string s2("hello world");
//	cout << s1.max_size() << endl;
//	cout << s2.max_size() << endl;
//
//	cout << s1.size() << endl;
//	cout << s2.size() << endl;
//
//	cout << s1.capacity() << endl;
//	cout << s2.capacity() << endl;
//
//	cout << s1 << endl;
//	cout << s2 << endl;
//
//	s2.clear();
//	cout << s1.size() << endl;
//	cout << s2.size() << endl;
//
//	cout << s1.capacity() << endl;
//	cout << s2.capacity() << endl;
//
//	return 0;
//}

//int main()
//{
//	string s1;
//	cout << "size:" << s1.size() << endl;
//	cout << "capacity:" << s1.capacity() << endl;
//	cout << s1 << endl;
//
//	s1.resize(20, 'x');
//	cout << "size:" << s1.size() << endl;
//	cout << "capacity:" << s1.capacity() << endl;
//
//	string s2("hello world");
//	s2.resize(20, 'x');
//	cout << s2 << endl;
//	cout << "size:" << s2.size() << endl;
//	cout << "capacity:" << s2.capacity() << endl;
//
//	s2.resize(5);
//	cout << s2 << endl;
//	cout << "size:" << s2.size() << endl;
//	cout << "capacity:" << s2.capacity() << endl;
//
//	string s3;
//	cout << "size:" << s3.size() << endl;
//	cout << "capacity:" << s3.capacity() << endl;
//	s3.reserve(40);
//	cout << "size:" << s3.size() << endl;
//	cout << "capacity:" << s3.capacity() << endl;
//
//	string s4;
//	int oldCp = s4.capacity();
//	for (char ch = 0; ch < 127; ch++)
//	{
//		s4 += ch;
//		if (oldCp != s4.capacity())
//		{
//			cout << "增容：" << oldCp << "->" << s4.capacity() << endl;
//			oldCp = s4.capacity();
//		}
//	}
//	cout << s4 << endl;
//	return 0;
//}

//获取域名
string GetDomain(const string& url)
{
	size_t pos = url.find("://");
	if (pos != string::npos)
	{
		size_t start = pos + 3;
		size_t end = url.find('/', start);
		if (end != string::npos)
		{
			return url.substr(start, end - start);
		}
		else
		{
			return string();
		}
	}
}

string GetProtocol(const string& url)
{
	size_t pos =url.find("://");
	if (pos != string::npos)
	{
		return url.substr(0, pos - 0);

	}
	else
	{
		string s;
		return s;
	}

}

int main()
{
	string s1("hello world");
	cout << s1 << endl;   //调用operator<<(cout,s1)
	cout << s1.c_str() << endl;   //调用operator<<(cout,const char*)

	s1.resize(20);
	s1 += "!!!!";
	cout << s1 << endl;   //调用operator<<(cout,s1)
	cout << s1.c_str() << endl;   //调用operator<<(cout,const char*)

	cout << strlen(s1.c_str()) << endl;
	cout << s1.size() << endl << endl;


	//假设要求取出文件的后缀
	string filename = "test.txt.zip";
	size_t pos = filename.rfind(".");
	if (pos != string::npos)
	{
		/*string suff(filename, pos, filename.size() - pos);
		string suff(filename, pos);
		string suff = filename.substr(pos, filename.size() - pos);*/
		string suff = filename.substr(pos);

		cout << suff << endl;
	}

	//要求写一个程序分别取出域名和 协议名
	string url1 = "https://mp.csdn.net/mp_blog/manage/article?spm=1010.2135.3001.5448";
	
	cout << GetDomain(url1) << endl;
	cout << GetProtocol(url1) << endl;
	return 0;
}





























//namespace ly
//{
//	class string
//	{
//	public:
//		string(const char* str)
//		{
//			_str = new char[strlen(str) + 1];
//			strcpy(_str, str);
//		}
//
//		char& operator[](size_t i)
//		{
//			return _str[i];
//		}
//
//		size_t size()
//		{
//			return strlen(_str);
//		}
//	private:
//		char* _str;
//
//	};
//}
////int main()
////{
////	ly::string s("hello world");
////	cout << s[2] << endl;
////	cout << s.operator[](2) << endl;
////	
////	for (size_t i = 0; i < s.size(); i++)
////	{
////		cout << s[i] << " ";
////	}
////	cout << endl;
////	for (size_t i = 0; i < s.size(); i++)
////	{
////		s[i] += 1;
////	}
////	for (size_t i = 0; i < s.size(); i++)
////	{
////		cout << s[i] << " ";
////	}
////	cout << endl;
////	return 0;
////}
//
//class B
//{
//public:
//	B(int b = 0)
//		:_b(b)
//	{}
//	B(const B& bb)
//		:_b(bb._b)
//	{
//		cout << "B(const B& bb) " << endl;
//	}
//	B& operator=(const B& bb)
//	{
//		cout << "B& operator=(const B& bb)" << endl;
//		if (this != &bb)
//		{
//			_b = bb._b;
//		}
//		return *this;
//	}
//private:
//	int _b;
//};
//
//class C
//{
//public:
//	C(int c1 = 0, int c2 = 0)
//		:_c1(c1)
//		, _c2(c2)
//	{}
//private:
//	int _c1;
//	int _c2;
//
//};
//
//class A
//{
//public:
//private:
//	//默认生成的构造函数对基本类型成员变量是不做处理的
//	//有些比较新的编译器也有可能会初始化成0，但是大多数编译器都不会处理，我们要当成不初始化
//	//基本类型不处理，是c++语法设计的一个小缺陷
//	int _a1 = 1;     //这里不是初始化，是给缺省值
//	int _a2 = 2;
//
//	B _b = B(1);
//	C _c = { 1,1 };
//};
//
//class D
//{
//public:
//	//D的构造函数中，在哪里调用B的默认构造函数呢
//	//对象定义的时候会自动调用构造函数
//	//构造函数的初始化列表可以认为是成员变量定义初始化的地方
//	//初始化列表，你显示的写或是不写，都会走一遍
//	D()
//	{}
//private:
//	int _d = 0;    //成员声明
//	B _b;
//};
//
////有三种变量必须在初始化列表初始化
////1、const、2、引用3、没有默认构造函数的成员对象
//
////int main()
////{
////	A aa;
////	D d;  //对象定义的时候，成员也作为对象的一部分定义出来了
////	return 0;
////}
//
////析构函数
//class Date
//{
//public:
//	~Date()
//	{
//		//这个类没有什么资源需要清理
//		//所以不写析构函数，编译器自动生成的就可以
//	}
//private:
//	int _year = 0;
//	int _month = 1;
//	int _day = 0;
//
//	B _b = 10;
//};
//
//namespace bit
//{
//	class string
//	{
//	public:
//		string(const char* str = "")
//			:_str(new char[strlen(str) + 1])
//
//		{
//			strcpy(_str, str);
//		}
//		//s2(s1)
//		string(const string& s)
//			:_str(new char[strlen(s._str) + 1])
//		{
//			strcpy(_str, s._str);
//		}
//
//		//s1=s3
//		string& operator=(const string& s)
//		{
//			if (this != &s)
//			{
//				delete[] _str;
//				_str = new char[strlen(s._str) + 1];
//				strcpy(_str, s._str);
//			}
//			return *this;
//
//
//		}
//		char& operator[](size_t i)
//		{
//			return _str[i];
//		}
//		size_t size()
//		{
//			return strlen(_str);
//		}
//		~string()
//		{
//			cout << "~string()" << endl;
//			delete[] _str;
//			_str = nullptr;
//		}
//	private:
//		char* _str;
//	};
//}
//
//class F
//{
//private:
//	//默认生成的析构函数并不是什么都不做
//	//基本类型不处理，自定义类型，会去调用他的析构函数
//	int _a;
//	bit::string _s;
//};
//
//int main()
//{
//	Date d;//析构函数不是完成对象的销毁
//			//这个对象是存在函数栈帧里的，函数结束，栈帧销毁，对象就销毁了
//
//	bit::string s1("hello world");
//	//针对s1有两块空间要销毁
//	//第一：s1对象本身，他是函数结束，栈帧销毁，他就销毁
//	//第二：s1里面的_str指向的堆上的空间，他是析构函数清理的
//
//	bit::string s2;
//	F ff;
//	return 0;
//}
//
//
//int main()
//{
//	//浅拷贝（值拷贝）的类
//	Date d1;
//	Date d2(d1);
//	Date d3 = d1;
//	Date d4;
//	d4 = d1;
//
//	bit::string s1("hello world");
//	bit::string s2(s1);
//	bit::string s3("hello bit");
//	s1 = s3;
//	return 0;
//}